package logger

import (
	"fmt"
	"log"
	"os"
	"sync"
	"time"
)

// Logger 定义日志接口
type Logger interface {
	Info(msg string, fields ...interface{})
	Warn(msg string, fields ...interface{})
	Error(msg string, fields ...interface{})
	Fatal(msg string, fields ...interface{})
}

// StandardLogger 实现Logger接口的标准日志器
type StandardLogger struct {
	mu       sync.Mutex
	infoLog  *log.Logger
	warnLog  *log.Logger
	errorLog *log.Logger
	fatalLog *log.Logger
}

// NewLogger 创建一个新的日志器实例
func NewLogger() Logger {
	// 设置日志前缀格式
	prefix := "[%s] "

	// 创建日志器实例
	logger := &StandardLogger{
		infoLog:  log.New(os.Stdout, fmt.Sprintf(prefix, "INFO"), log.LstdFlags),
		warnLog:  log.New(os.Stdout, fmt.Sprintf(prefix, "WARN"), log.LstdFlags),
		errorLog: log.New(os.Stderr, fmt.Sprintf(prefix, "ERROR"), log.LstdFlags),
		fatalLog: log.New(os.Stderr, fmt.Sprintf(prefix, "FATAL"), log.LstdFlags),
	}

	return logger
}

// formatMessage 格式化日志消息和字段
func formatMessage(msg string, fields []interface{}) string {
	if len(fields) == 0 {
		return msg
	}

	// 确保fields的数量是偶数（key-value对）
	if len(fields)%2 != 0 {
		// 如果不是偶数，添加一个空值作为最后一个字段的值
		fields = append(fields, "")
	}

	result := msg + " |"
	for i := 0; i < len(fields); i += 2 {
		key := fmt.Sprintf("%v", fields[i])
		value := fmt.Sprintf("%v", fields[i+1])
		result += fmt.Sprintf(" %s=%s", key, value)
	}
	return result
}

// Info 记录信息级别日志
func (l *StandardLogger) Info(msg string, fields ...interface{}) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.infoLog.Println(formatMessage(msg, fields))
}

// Warn 记录警告级别日志
func (l *StandardLogger) Warn(msg string, fields ...interface{}) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.warnLog.Println(formatMessage(msg, fields))
}

// Error 记录错误级别日志
func (l *StandardLogger) Error(msg string, fields ...interface{}) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.errorLog.Println(formatMessage(msg, fields))
}

// Fatal 记录致命错误级别日志并退出程序
func (l *StandardLogger) Fatal(msg string, fields ...interface{}) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.fatalLog.Println(formatMessage(msg, fields))
	os.Exit(1)
}

// Time 计算并记录操作执行时间的辅助函数
func Time(logger Logger, operation string, fn func() error) error {
	start := time.Now()
	err := fn()
	duration := time.Since(start)
	
	if err != nil {
		logger.Error(fmt.Sprintf("%s failed", operation), "duration", duration, "error", err)
	} else {
		logger.Info(fmt.Sprintf("%s completed", operation), "duration", duration)
	}
	
	return err
}